import java.awt.Color;
import java.util.PriorityQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;

import javax.swing.JOptionPane;

/**
 * MessageReceiver staat in voor het ontvangen van berichten.
 * Ontvangen berichten worden dan doorgespeeld naar de juiste objecten.
 * @author Tom
 *
 */
public class MessageReceiver extends Thread {
	
	private SpelManager spelManager;
	private Multicaster multicaster;	// handles the socket that sends and receives messages
	private boolean applicationExit;
	private Message joinAccepted;
	private PriorityBlockingQueue<Message> priorityQueue;
	
	
	/**
	 * Constructor
	 */
	public MessageReceiver(Multicaster mc, SpelManager spelManager) {
		multicaster = mc;
		this.spelManager = spelManager;
		applicationExit = false;
		joinAccepted = null;
		priorityQueue = new PriorityBlockingQueue<Message>();
	}
	
	public Message getJoinAccepted() {
		return joinAccepted;
	}
	
	public void setApplicationExit(boolean appExit) {
		applicationExit = appExit;
	}
	
	public PriorityBlockingQueue<Message> getPriorityQueue() {
		return priorityQueue;
	}
	
	public void run() {
		Message msg = null;
		
		while (!applicationExit)
		{
			try {
				msg = multicaster.receive();
				//JOptionPane.showMessageDialog(null, "Bericht van " + msg.getZenderID() + " ontvangen door: " + spelManager.eigenID);
				// DIT moet gecheckt worden bij het leegmaken van de queue
				if ( msg != null && (msg.voorOntvanger(Message.VOOR_IEDEREEN) || msg.voorOntvanger(spelManager.eigenID) || (msg.voorOntvanger(Message.VOOR_BAAS) && spelManager.isBaas()))) {
					switch (msg.type) {
					// TODO: alles in een queue steken, want kan zijn dat we deze dingen nog moeten uitvoeren					
					
					case JOIN:
						if (spelManager.eigenID != msg.getZenderID() && spelManager.isBaas())
							spelManager.answerOnJoin((Color) msg.getObject(), msg.getZenderID());
						break;
					case LEAVE:
						if (spelManager.eigenID < 0)
							priorityQueue.offer(msg);
						else if (spelManager.eigenID != msg.getZenderID())
							spelManager.verwijderSpeler(msg.getZenderID());
						break;
					case JOIN_ACCEPTED:
						spelManager.acceptJoin((JoinData) msg.getObject());						
						break;
					case HERKIES_KLEUR:
						spelManager.herkiesKleur();
						break;
					case ZET:
						if (spelManager.eigenID < 0)
						{
							//System.out.println("dit is fout");
							priorityQueue.offer(msg);
						}
						else
							spelManager.ontvangZet(msg.getZenderID(), (Integer) msg.getObject());
						break;
					case VRAAG_LOCK_KOLOM:
						break;
					case GEEF_LOCK:
						break;
					case REQUEST:
						//System.out.println(msg.toString());
						//spelManager.lock.onRequestReceived(msg.zenderID);
						break;
					case REPLY:
						//notifyAll();
						break;
					case IK_LEEF:
						if (spelManager.eigenID != msg.getZenderID())
							spelManager.ikLeef(msg.getZenderID());
						break;
					case ELECTION_ANSWER:
						if (spelManager.eigenID >= 0)
							spelManager.receiveElectionAnswer();
						break;
					case ELECTION_REQUEST:
						if (spelManager.eigenID >= 0)
							spelManager.receiveElectionRequest(msg.zenderID);
						break;
					case ELECTION_COORDINATE:
						//if (spelManager.eigenID >= 0)
							spelManager.receiveElecionCoordinate(msg.zenderID);
						break;
					case NEW_PLAYER:
						if (spelManager.eigenID < 0)
							priorityQueue.offer(msg);
						else if (spelManager.eigenID != msg.getZenderID())
							spelManager.addSpeler(msg.zenderID, (Color) msg.object);
						break;
					case PAUZE:
						if (spelManager.eigenID < 0) {
							priorityQueue.offer(msg);
						} else
							spelManager.setPauze();
						break;
					case FAILURE:
						if (spelManager.eigenID < 0)
							priorityQueue.offer(msg);
						else 
							spelManager.verwijderSpeler((Integer) msg.object);
						break;
					default:
						//System.out.println("default");
						break;
					}
				}						
					//holdBackQueue.add(msg);
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			// TODO: bij ontvanger van ELECTION_COORDINATE ook manager bij spelManager zetten
			// TODO: op ELECTION_REQUEST antwoorden met sendElectionAnswer van spelManager
			// TODO: bij HERKIES_KLEUR met SpelManager.herkiesKleur() opgeroepen worden
			// TODO: bij ACCEPT_JOIN roep SpelManager.acceptJoin(kleur, zenderID) op
			// TODO: nog kijken op welke plaatsen we moeten checken of het spel ondertussen niet is afgelopen
			// bv. bij het herzenden bij een lock		
		}
	}
	
}
